﻿using System;
using System.Reflection;
using System.Threading;
using WatiNCF;

namespace WatiNCF
{
    public static class FluentHelper
    {
        /// <summary>
        /// Provides a fluent interface extension which allows the injection of the specified
        /// property to inject into a property matching that type on the target object.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="TResult">The type of the result.</typeparam>
        /// <param name="target">The target to inject the property into.</param>
        /// <param name="propertyToInject">The property to inject.</param>
        /// <returns></returns>
        public static TResult With<T, TResult>(this object target, T propertyToInject) 
            where T : class
            where TResult : class
        {
            PropertyInfo[] properties = target.GetType()
                .GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);
            foreach (var property in properties)
            {
                if (property.GetType() == typeof(T))
                {
                    property.SetValue(target, propertyToInject, null);
                }
            }

            return target as TResult;
        }

        /// <summary>
        /// Provides a fluent interface extension which allows an action to be performed
        /// using a page controller and return an instance of the target controller.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="target">The target.</param>
        /// <param name="action">The action to perform.</param>
        /// <returns>The target object</returns>
        public static T Do<T>(this IPageController<T> target, Action action) where T : class
        {
            action();
            return target as T;
        }

        public static T Wait<T>(this IPageController<T> target, int timeToWait) where T : class
        {
            Thread.Sleep(timeToWait);
            return target as T;
        }

        /// <summary>
        /// Provides a fluent interface extension which allows an action to be performed
        /// using a page controller, passing the controller as a parameter to the action,
        /// and returns an instance of the target controller.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="target">The target to perform the action on.</param>
        /// <param name="action">The action to perform.</param>
        /// <returns>The target object</returns>
        public static T Do<T>(this IPageController<T> target, Action<T> action) where T : class
        {
            action(target as T);
            return target as T;
        }
    }
}